home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- {* AACDate *}
- {* Copyright (c) Julian M Bucknall 1998 *}
- {* All rights reserved. *}
- {*********************************************************}
- {* Various date calculation routines *}
- {*********************************************************}
-
- {Note: this unit is released as freeware. In other words, you are free
- to use this unit in your own applications, however I retain all
- copyright to the code. JMB}
-
- unit AACDate;
-
- interface
-
- function GetDateForDayOfMonth(aWhichOne : integer;
- aDay : integer;
- aMonth : integer;
- aYear : integer) : TDateTime;
- {-returns the date of the aWhichOne'th aDay of aMonth/aYear; if
- there is no such date, returns 0.0}
-
- procedure GetISODate(aDate : TDateTime;
- var aYear : integer;
- var aWeek : integer;
- var aDay : integer);
- {-return the ISO date (year, week number and day of week) for a
- given date. Under the ISO system, week 1 of a year is the week
- containing the first Thursday of the year; a week starts with
- a Monday and ends with a Sunday.}
-
-
- implementation
-
- uses
- SysUtils;
-
- function GetDateForDayOfMonth(aWhichOne : integer;
- aDay : integer;
- aMonth : integer;
- aYear : integer) : TDateTime;
- var
- Month1st : TDateTime;
- Day1st : integer;
- begin
- {validate}
- if (aDay < 1) or (aDay > 7) then
- raise Exception.Create('The day should be between 1 (Sunday) and 7 (Saturday)');
- if (aMonth < 1) or (aMonth > 12) then
- raise Exception.Create('The month should be between 1 and 12');
- if (aWhichOne < 1) or (aWhichOne > 5) then
- raise Exception.Create('The WhichOne value should be between 1 (first) and 5 (fifth)');
- {calculate}
- Month1st := EncodeDate(aYear, aMonth, 1);
- Day1st := DayOfWeek(Month1st);
- if (Day1st <= aDay) then
- Result := aDay - Day1st + ((aWhichOne-1) * 7) + Month1st
- else
- Result := aDay - Day1st + (aWhichOne * 7) + Month1st;
- if (Result - Month1st + 1) > MonthDays[IsLeapYear(aYear), aMonth] then
- Result := 0.0;
- end;
-
- function CalcFirstWeek(aYear : integer) : TDateTime;
- {-returns the date of the Monday of week 1 of the given year}
- const
- DOWThu = 5;
- var
- Month1stJan : TDateTime;
- Day1stJan : integer;
- begin
- Month1stJan := EncodeDate(aYear, 1, 1);
- Day1stJan := DayOfWeek(Month1stJan);
- if (Day1stJan <= DOWThu) then
- Result := DOWThu - Day1stJan + Month1stJan - 3
- else
- Result := DOWThu - Day1stJan + Month1stJan + 4;
- end;
-
- procedure GetISODate(aDate : TDateTime;
- var aYear : integer;
- var aWeek : integer;
- var aDay : integer);
- var
- WeekOneStart: TDateTime;
- Year : word;
- Month : word;
- Day : word;
- begin
- {calculate the date of the Monday for the first week for the date's
- year}
- DecodeDate(aDate, Year, Month, Day);
- WeekOneStart := CalcFirstWeek(Year);
- {if the given date is greater than/equal to the 1st week start date
- calculate the week number and day number}
- if (aDate >= WeekOneStart) then begin
- aYear := Year;
- aWeek := (Trunc(aDate - WeekOneStart) div 7) + 1;
- aDay := (Trunc(aDate - WeekOneStart) mod 7) + 1;
- {check to see if the given date could appear in the first week of
- the following year, if so so do the same calculation again, but
- for the next year}
- if ((aDate - WeekOneStart) > 364) then begin
- WeekOneStart := CalcFirstWeek(Year+1);
- if (aDate >= WeekOneStart) then begin
- aYear := Year+1;
- aWeek := (Trunc(aDate - WeekOneStart) div 7) + 1;
- aDay := (Trunc(aDate - WeekOneStart) mod 7) + 1;
- end;
- end;
- end
- {if the given date is less than the 1st week start date, it'll be in
- the last week of the previous year, so do the same calculation
- again, but for the prior year}
- else begin
- dec(Year);
- WeekOneStart := CalcFirstWeek(Year);
- aYear := Year;
- aWeek := (Trunc(aDate - WeekOneStart) div 7) + 1;
- aDay := (Trunc(aDate - WeekOneStart) mod 7) + 1;
- end;
- end;
-
- end.
-